Skip to content

[Chakra v3] Fix data fetching regression with the SSR rendering (@W-18822712@)#2785

Merged
vmarta merged 28 commits intofeature/chakra-ui-upgrade-v3from
vm/ssr-regression-fix
Jul 15, 2025
Merged

[Chakra v3] Fix data fetching regression with the SSR rendering (@W-18822712@)#2785
vmarta merged 28 commits intofeature/chakra-ui-upgrade-v3from
vm/ssr-regression-fix

Conversation

@vmarta
Copy link
Contributor

@vmarta vmarta commented Jul 10, 2025

In the chakra v3 branch, we've observed a data-fetching regression with the server rendering, where most of the queries were not being run. Only the queries in the very top level components (like App, AppConfig) would get run.

It turns out that react-ssr-prepass and Chakra's use of React 18's useInsertionEffect are not compatible. When prepass is walking through the component tree, it needs to ignore the useInsertionEffect.. similar to how it's already ignoring useEffect and useLayoutEffect.

As a workaround, we've set useInsertionEffect to a no-op from within our SDK.

There's also another similar issue where Chakra's Portal component tries to access document which does not exist on the server side. Now we've created our own safe version of Portal that runs only on the client side.

Remaining todos:

  • add E2E test? I don't think there's such test yet for verifying the server-rendered page.

How to test-drive the PR

  1. Navigate to http://localhost:3000/?__server_only
  2. Verify that the Shop Products section with its product data/images appear on the page.
  3. If yes, that means that the query to fetch data for that section was run successfully
  4. Now navigate to other pages (PLP, PDP) and verify that the resulting pages are very similar to the normal/client side version.

If you want to go further, you can also verify that there is no more error caught during prepass.

  1. Run npm run start:inspect and make sure that you see the correct server logs through your Chrome browser.
  2. Add a debugger according to the screenshot below
  3. Navigate to http://localhost:3000/?__server_only
  4. Verify that there is no error caught.
Arc 2025-07-14 at 13 12 53@2x

@cc-prodsec
Copy link
Collaborator

cc-prodsec commented Jul 10, 2025

🎉 Snyk checks have passed. No issues have been found so far.

security/snyk check is complete. No issues have been found. (View Details)

license/snyk check is complete. No issues have been found. (View Details)

// (see https://github.com/FormidableLabs/react-ssr-prepass/issues/84)
// - Why useInsertionEffect? Chakra v3 hooks (like useDisclosure, useBreakpointValue, useMediaQuery, useCallbackRef) rely on it for rendering optimization.
// - Why no-op? useInsertionEffect is meant for client side only. So on the server, we wanted prepass to ignore it.
React.useInsertionEffect = () => {} // no-op
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting fix! I'd imagine it's hard to find this out, good job!

I'm wondering if you want to move this line to near the ssr-prepass related code, for example in packages/pwa-kit-react-sdk/src/ssr/universal/components/with-react-query/index.js

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking that we needed to set it to no-op very early on, at the start of entry point. But I can try moving it to with-react-query file and see whether the time matters or not.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, just trying to understand the behavior due to this change. So all the components that use useInsertionEffect will now have a slight delay (may be not noticable) for the css application?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just tried moving the line to the with-react-query file, but the app errors out. So I'm leaving the code change as it is now, but I've added some comment near the prepass call.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@unandyala there shouldn't be any delay nor any change in behaviour. The workaround we implemented here is only for the server side. So when useInsertionEffect is called on the client side, it should behave the same as before.

🤔 Is there something else I need to consider? Let me know please, thanks.

@vmarta vmarta marked this pull request as ready for review July 11, 2025 22:41
@vmarta vmarta requested a review from a team as a code owner July 11, 2025 22:41
- Send PWA Kit events to Data Cloud [#318] (https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2229)
- Fix dependencies vulnerabilities [#2338](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2338)
- Fix accessibility issues [#2375](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2375)
- Fix data-fetching regression with SSR rendering [#2785](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2785)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we want to be a little be more clear on this for discoverability purposes.

We can either say what you have but mention + "due to chakra v3 upgrade".

So we can say something like "Ensure client-side only API's are called on the server"

I'm also ok with leaving it as is.

Comment on lines +278 to +283
if (typeof window === 'undefined') {
// Render nothing on the server side. Otherwise, the Portal component would break SSR and its data fetching.
// Portal would call Ark UI's useEnvironmentContext hook, which tries to access `document` that doesn't exist on the server.
return
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having this one off logic, should we create a component..

Also there is this new that might fit the bill to wrap the render portion of this render. Not that I really want to solidify the Island component, but it's there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just trying to understand the behavior here - since the portal components are closed by default there shouldn't be any performance impact, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@unandyala Yeah I think there shouldn't be any performance impact. But what performance-specific scenario or metric were you thinking of?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vmarta There are a few components that is using Portal in its render. Would this happen whenever Portal is used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexvuong yeah, I'm going to replace all usage of Portal with our own version, which will render only on the client side.

@@ -1,4 +1,6 @@
## v4.0.0-extensibility-preview.5 (May 06, 2025)
- Fix data-fetching regression with SSR rendering [#2785](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2785)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar comment as above, but it would be nice to angle this in a positive light since "regression" almost implies we unintentionally broke something and released it and fixed it. Since we didn't release it we might be able to say "Account for rending components that use reacts useInsertionEffect hook on the server"

vmarta added 2 commits July 14, 2025 09:56
The setting of useInsertionEffect to a no-op had to be done in another file.
vmarta added 5 commits July 14, 2025 12:30
I didn't want to add test to react-rendering.test.js because my code change isn't much for testing. So I decided to add tests for another file instead.
expect(parseFloat(timer.metrics[0].duration)).toBeGreaterThan(0)
})

test('warns when mark name is undefined', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To meet the test coverage, I decided to add tests for this performance util. Yes, it's not related to the PR. But there isn't much changes in the react-rendering.js file that's worthy for testing.

@vmarta vmarta merged commit eb90845 into feature/chakra-ui-upgrade-v3 Jul 15, 2025
33 checks passed
@vmarta vmarta deleted the vm/ssr-regression-fix branch July 15, 2025 17:23
alexvuong pushed a commit that referenced this pull request Jul 16, 2025
…822712@) (#2785)

* Remove call to withLegacyGetProps

* Debugging

* Revert change to AppConfig

* Add todos

* Try commenting out the problematic Chakra hooks

Including those components that also call `useDisclosure`.

* Revert "Try commenting out the problematic Chakra hooks"

This reverts commit 970b97e.

* Create a safe version of useDisclosure

* Fix react-ssr-prepass lack of no-op for useInsertionEffect

* Don't render Portal on server side

* Show header again

* Revert "Create a safe version of useDisclosure"

This reverts commit 669f2eb.

* This Portal is already rendered only on client side

* Render nothing on server side

* Clean up code

* Remove unnecessary category check

* Add comment

* Update changelog files

* Existing tests are now passing again

* Revert change to the skeleton

* Add a comment closer to the prepass call

The setting of useInsertionEffect to a no-op had to be done in another file.

* Create a safe version of Portal

* Update changelog files

* Add comments to clarify

* Check first whether useInsertionEffect is defined or not

* Add more tests to pass test coverage

I didn't want to add test to react-rendering.test.js because my code change isn't much for testing. So I decided to add tests for another file instead.

* Add comment
vmarta added a commit that referenced this pull request Jul 29, 2025
Brought back the useInsertionEffect no-op from PR #2785.
vmarta added a commit that referenced this pull request Jul 29, 2025
…6@) (#2938)

* Fix server side rendering

Brought back the useInsertionEffect no-op from PR #2785.

* Bring back this comment

* Update CHANGELOG.md
sf-shikhar-prasoon added a commit that referenced this pull request Aug 1, 2025
* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/components/product-view-modal/bundle.jsx

* refactor translations in src/components/product-view-modal/index.jsx

* refactor translations in src/components/promo-code/index.jsx

* refactor translations in src/components/promo-popover/index.jsx

* update refactoring-checklist.md

* refactor translations in src/components/recommended-products/index.jsx

* refactor translations in src/components/register/index.jsx

* refactor translations in src/components/reset-password/index.jsx

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/components/search/index.jsx

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor translations in src/components/search/partials/recent-searches.jsx

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/components/social-login/index.jsx

* update refactoring-checklist.md

* refactor translations in src/components/store-locator-modal/store-locator-content.jsx

* refactor translations in src/components/store-locator-modal/store-locator-input.jsx

* refactor translations in src/components/store-locator-modal/stores-list.jsx

* refactor translations in src/components/swatch-group/index.jsx

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/components/toggle-card/index.jsx

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/components/with-registration/index.jsx

* update refactoring-checklist.md

* refactor translations in src/pages/account/addresses.jsx

* update refactoring-checklist.md

* refactor translations in src/pages/account/index.jsx

* refactor translations in src/pages/account/order-detail.jsx

* refactor translations in src/pages/account/order-history.jsx

* update refactoring-checklist.md

* refactor translations in src/pages/account/profile.jsx

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor translations in src/pages/account/wishlist/index.jsx

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* update refactoring-checklist.md

* refactor translations in src/pages/account/wishlist/partials/wishlist-primary-action.jsx

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/pages/account/wishlist/partials/wishlist-secondary-button-group.jsx

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/pages/cart/hooks/use-cart-operations.js

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/pages/cart/partials/cart-cta.jsx

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/pages/cart/partials/cart-recommendations.jsx

* refactor translations in src/pages/cart/partials/cart-secondary-button-group.jsx

* refactor translations in src/pages/cart/partials/cart-skeleton.jsx

* update refactoring-checklist.md

* refactor translations in src/pages/cart/partials/cart-title.jsx

* refactor translations in src/pages/cart/partials/empty-cart.jsx

* refactor translations in src/pages/checkout/confirmation.jsx

* update refactoring-checklist.md

* refactor translations in src/pages/checkout/index.jsx

* refactor translations in src/pages/checkout/partials/cc-radio-group.jsx

* refactor translations in src/pages/checkout/partials/checkout-footer.jsx

* refactor translations in src/pages/checkout/partials/checkout-header.jsx

* update refactoring-checklist.md

* refactor translations in src/pages/checkout/partials/contact-info.jsx

* refactor translations in src/pages/checkout/partials/login-state.jsx

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor translations in src/pages/checkout/partials/payment-form.jsx

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor translations in src/pages/checkout/partials/payment.jsx

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor translations in src/pages/checkout/partials/shipping-address-selection.jsx

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor translations in src/pages/checkout/partials/shipping-address.jsx

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor translations in src/pages/checkout/partials/shipping-options.jsx

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/pages/home/index.jsx

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/pages/login/index.jsx

* refactor translations in src/pages/page-not-found/index.jsx

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/pages/product-detail/partials/information-accordion.jsx

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/pages/product-detail/partials/recommended-products-section.jsx

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/pages/product-list/partials/empty-results.jsx

* update refactoring-checklist.md

* refactor translations in src/pages/product-list/partials/category-links.jsx

* update refactoring-checklist.md

* refactor translations in src/pages/product-list/partials/color-refinements.jsx

* refactor translations in src/pages/product-list/partials/page-header.jsx

* update refactoring-checklist.md

* refactor translations in src/pages/product-list/partials/product-list-header.jsx

* update refactoring-checklist.md

* refactor translations in src/pages/product-list/partials/product-list-title.jsx

* refactor translations in src/pages/product-list/partials/radio-refinements.jsx

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/pages/product-list/partials/selected-refinements.jsx

* refactor translations in src/pages/product-list/partials/size-refinements.jsx

* refactor translations in src/pages/product-list/partials/sort.jsx

* refactor translations in src/pages/registration/index.jsx

* refactor translations in src/pages/reset-password/index.jsx

* refactor translations in src/pages/reset-password/reset-password-landing.jsx

* refactor translations in src/pages/social-login-redirect/index.jsx

* update refactoring-checklist.md

* lint

* remove scripts

* fix test

* W-19151166 fix product view modal cart (#2924)

* fix product view modal on cart page

* [V4] Make sure that the server side rendering works again (@W-19159606@) (#2938)

* Fix server side rendering

Brought back the useInsertionEffect no-op from PR #2785.

* Bring back this comment

* Update CHANGELOG.md

* build translations

* Revert "remove scripts"

This reverts commit 39705be.

* refactor translations in src/hooks/use-dnt-notification.js

* refactor translations in src/hooks/use-add-to-cart-modal.js

* refactor translations in src/components/register/index.jsx

* refactor translations in src/components/item-variant/item-image.jsx

* refactor translations in src/components/item-variant/item-attributes.jsx

* refactor translations in src/components/email-confirmation/index.jsx

* refactor translations in src/components/action-card/index.jsx

* refactor translations in src/pages/product-list/partials/product-list-header.jsx

* minor fixes

* update translations readme

* refactor translations in src/components/display-price/current-price.jsx

* refactor translations in src/components/display-price/list-price.jsx

* refactor translations in src/components/forms/address-fields.jsx

* refactor translations in src/components/forms/profile-fields.jsx

* update refactoring-checklist.md

* refactor translations in src/components/list-menu/list-menu.jsx

* refactor translations in src/components/locale-text/index.jsx

* refactor translations in src/components/offline-banner/index.jsx

* refactor translations in src/components/order-summary/index.jsx

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* update refactoring-checklist.md

* refactor translations in src/hooks/use-add-to-cart-modal.js

* refactor translations in src/hooks/use-derived-product.js

* refactor translations in src/hooks/use-product-view-modal.js

* refactor translations in src/page-designer/layouts/carousel/index.jsx

* refactor translations in src/pages/checkout/partials/checkout-footer.jsx

* refactor translations in src/pages/checkout/partials/checkout-header.jsx

* refactor translations in src/pages/home/index.jsx

* refactor translations in src/pages/page-not-found/index.jsx

* refactor translations in src/pages/product-list/partials/color-refinements.jsx

* refactor translations in src/pages/product-list/partials/empty-results.jsx

* refactor translations in src/pages/product-list/partials/sort.jsx

* refactor translations in src/components/action-card/index.jsx

* refactor translations in src/components/action-card/index.jsx

* refactor translations in src/components/action-card/index.jsx

* refactor translations in src/components/display-price/current-price.jsx useMemo

* refactor translations in src/components/display-price/list-price.jsx useMemo

* refactor translations in src/components/drawer-menu/drawer-menu.jsx useMemo

* refactor translations useMemo in src/components/email-confirmation/index.jsx

* refactor translations useMemo in src/components/field/index.jsx

* refactor translations useMemo in src/components/footer/index.jsx

* refactor translations useMemo in src/components/forms/address-fields.jsx

* refactor translations useMemo in src/components/forms/credit-card-fields.jsx

* refactor translations with useMemo in src/components/forms/form-action-buttons.jsx

* refactor translations in src/components/forms/login-fields.jsx with useMemo

* refactor translations in src/components/forms/password-requirements.jsx with useMemo

* refactor translations in src/components/forms/profile-fields.jsx with useMemo

* refactor translations in src/components/forms/promo-code-fields.jsx with useMemo

* refactor translations in src/components/forms/update-password-fields.jsx with useMemo

* refactor translations in src/components/forms/useLoginFields.jsx with useMemo

* refactor translations with useMemo in src/components/forms/useProfileFields.jsx

* refactor translations with useMemo in src/components/forms/usePromoCodeFields.jsx

* refactor translations with useMemo in src/components/forms/useRegistrationFields.jsx

* refactor translations in src/components/forms/useResetPasswordFields.jsx with useMemo

* refactor translations in src/components/forms/useUpdatePasswordFields.jsx with useMemo

* refactor translations in src/components/header/index.jsx with useMemo

* refactor translations in src/components/item-variant/item-attributes.jsx with useMemo

* refactor translations in src/components/item-variant/item-image.jsx useMemo

* refactor translations in src/components/item-variant/item-price.jsx useMemo

* refactor translations in src/components/list-menu/list-menu.jsx useMemo

* refactor translations in src/components/offline-banner/index.jsx useMemo

* refactor translations in src/components/order-summary/index.jsx useMemo

* refactor translations in src/components/pagination/index.jsx useMemo

* refactor translations in src/components/passwordless-login/index.jsx with useMemo

* refactor translations in src/components/product-scroller/index.jsx useMemo

* refactor translations in src/components/product-tile/index.jsx useMemo

* refactor translations in src/components/product-view-modal/bundle.jsx - useMemo

* refactor translations in src/components/product-view-modal/index.jsx - useMemo

* refactor translations in src/components/promo-code/index.jsx - useMemo

* refactor translations in src/components/promo-popover/index.jsx - useMemo

* refactor translations useMemo in src/components/quantity-picker/index.jsx

* refactor translations useMemo in src/components/recommended-products/index.jsx

* refactor translations useMemo in src/components/register/index.jsx

* refactor translations useMemo in src/components/reset-password/index.jsx

* refactor translations in src/components/search/index.jsx with useMemo

* refactor translations in src/components/search/partials/recent-searches.jsx with useMemo

* refactor translations in src/components/social-login/index.jsx with useMemo

* refactor translations useMemo in src/components/store-locator-modal/store-locator-content.jsx

* refactor translations useMemo in src/components/store-locator-modal/store-locator-input.jsx

* refactor translations useMemo in src/components/store-locator-modal/stores-list.jsx

* refactor translations useMemo in src/components/swatch-group/index.jsx

* refactor translations useMemo in src/components/toggle-card/index.jsx

* refactor translations useMemo in src/components/with-registration/index.jsx

* refactor translations useMemo in src/hooks/use-add-to-cart-modal.js

* refactor translations useMemo in src/hooks/use-dnt-notification.js

* refactor translations useMemo in src/hooks/use-product-view-modal.js

* refactor translations useMemo in src/page-designer/layouts/carousel/index.jsx

* refactor translations useMemo in src/pages/account/addresses.jsx

* refactor translations useMemo in src/pages/account/order-detail.jsx

* refactor translations useMemo in src/pages/account/order-history.jsx

* refactor translations useMemo in src/pages/account/profile.jsx

* refactor translations useMemo in src/pages/account/wishlist/index.jsx

* refactor translations with useMemo in src/pages/account/wishlist/partials/wishlist-primary-action.jsx

* refactor translations with useMemo in src/pages/account/wishlist/partials/wishlist-secondary-button-group.jsx

* refactor translations with useMemo in src/pages/cart/hooks/use-cart-operations.js

* refactor translations with useMemo in src/pages/cart/partials/cart-cta.jsx

* refactor translations with useMemo in src/pages/cart/partials/cart-recommendations.jsx

* refactor translations with useMemo in src/pages/cart/partials/cart-secondary-button-group.jsx

* refactor translations with useMemo in src/pages/cart/partials/cart-skeleton.jsx

* refactor translations with useMemo in src/pages/cart/partials/cart-title.jsx

* refactor translations with useMemo in src/pages/cart/partials/empty-cart.jsx

* refactor translations with useMemo in src/pages/checkout/confirmation.jsx

* refactor translations with useMemo in src/pages/checkout/index.jsx

* lint

* lint

* fix tests

* fix tests

* revert some changes

* revert

* remove automation scripts

* commit new translations

* pr feedback

* fix missing descriptions

* [V4] Update config parsing such that private slas client works again  (@W-19144103@) (#2925)

* Attempt at fixing private slas client

It works now. It requires tweaking the existing config parsing code.

* Clean up code

* Further work on migrating to default.js

* Revert to public slas client

* Empty commit

* Fix linting errors

* Fix the config in the test file

* Move these config properties according to alphabetical order

* W-19137621 Fix use-auth-modal Unit Tests (#2952)

* fix unit for use-auth-modal

* remove jest timeout

* lint fix

---------

Co-authored-by: Kevin He <kevin.he@salesforce.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Alex Vuong <alex.vuong@salesforce.com>
Co-authored-by: Vincent Marta <vmarta@salesforce.com>
Co-authored-by: sf-jie-dai <jie.dai@salesforce.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants